// This source is subject to the Microsoft Public License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Resources;
using System.Threading;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;

namespace QuoteAdvantage
{
   /// <summary>
   /// Screen for applying special discounting rules
   /// </summary>
   public class CustomDiscount : System.Web.UI.Page
   {      
      protected Engine         eng = null;
      protected Quote          objQuote = null;
      protected QuoteDetail    objParentItem = null;
      protected Guid           guidQuoteId;
      protected Organization   objOrganization = null;
      protected string m_strCloseUrl = "";
      protected string strDiscountPriceLabel;
      protected string strListPriceLabel;
      protected string strValidationProblems;
      protected string strCurrencySymbol;
      protected int nCurrencyFormatCode;
      protected ResourceManager m_mgrResource;
      protected System.Web.UI.WebControls.Label Label2;
      protected System.Web.UI.WebControls.Label Label3;
      protected System.Web.UI.WebControls.Label lblQuoteTotal;
      protected System.Web.UI.WebControls.TextBox txtPercentageDiscount;
      protected System.Web.UI.WebControls.TextBox txtTargetPrice;
      protected System.Web.UI.WebControls.Label lblQuoteTotalValue;
      protected System.Web.UI.WebControls.Label Label1;
      protected System.Web.UI.WebControls.Button btnUpdateValues;
      protected System.Web.UI.WebControls.LinkButton lnkCancel;
      protected System.Web.UI.WebControls.LinkButton lnkSave;
      protected System.Web.UI.HtmlControls.HtmlInputHidden txtInitialDiscount;
      protected System.Web.UI.HtmlControls.HtmlInputHidden txtInitialTargetPrice;
      protected string strRootCategoryId = "";

      private void Page_Load(object sender, System.EventArgs e)
      {
         if (Request.QueryString["CategoryId"] != null)
         {
            strRootCategoryId = Request.QueryString["CategoryId"];
         }
         
         // Set the culture and UI culture to the browser's accept language
         Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);
         Thread.CurrentThread.CurrentUICulture = new CultureInfo(Request.UserLanguages[0]);

         m_mgrResource = new ResourceManager("QuoteAdvantage.strings", typeof(CustomizeQuote).Assembly);
         eng = new Engine(this.Trace, m_mgrResource);
         guidQuoteId = new Guid(Request.QueryString["QuoteId"]);
         objQuote = eng.LoadQuote(guidQuoteId);
               
         LoadResources();

         if (!this.IsPostBack)
         {
            SetControlValues();
            btnUpdateValues.Attributes.Add("onclick", "return onUpdateValuesClicked()");
            lnkCancel.Attributes.Add("onclick", "return onCancelClicked()");
         }
      }

      #region Web Form Designer generated code
      override protected void OnInit(EventArgs e)
      {
         //
         // CODEGEN: This call is required by the ASP.NET Web Form Designer.
         //
         InitializeComponent();
         base.OnInit(e);
      }
      
      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      private void InitializeComponent()
      {    
         this.lnkCancel.Click += new System.EventHandler(this.lnkCancel_Click);
         this.lnkSave.Click += new System.EventHandler(this.lnkSave_Click);
         this.btnUpdateValues.Click += new System.EventHandler(this.btnUpdateValues_Click);
         this.Load += new System.EventHandler(this.Page_Load);

      }
      #endregion

      private void LoadResources() 
      {                                               
         lnkCancel.Text = m_mgrResource.GetString("cmdCancel"); 
         lnkSave.Text = m_mgrResource.GetString("cmdSave"); 
         objOrganization = eng.LoadOrganization();
         strCurrencySymbol = objOrganization.CurrencySymbol;
         nCurrencyFormatCode = objOrganization.CurrencyFormatCode;
      }

            
      private void SetControlValues()
      {
         decimal nPrice = objQuote.CalculateNonDiscountPrice();
         lblQuoteTotalValue.Text = nPrice.ToString("0.00");

         txtTargetPrice.Text = objQuote.CalculatePrice().ToString("0.00");

         RefreshView();

         txtInitialDiscount.Value = txtPercentageDiscount.Text;
         txtInitialTargetPrice.Value = txtTargetPrice.Text;
      }   
      
      private void RefreshView()
      {
         bool bCalculateTargetPrice = true;
         decimal nPrice = objQuote.CalculateNonDiscountPrice();
         txtPercentageDiscount.Text = txtPercentageDiscount.Text.Trim().Replace("$", "");
         txtPercentageDiscount.Text = txtPercentageDiscount.Text.Replace("%", "");
         txtTargetPrice.Text = txtTargetPrice.Text.Trim().Replace("$", "");
         txtTargetPrice.Text = txtTargetPrice.Text.Replace("%", "");

         if (txtTargetPrice.Text != "")
         {
            if (txtPercentageDiscount.Text.Trim() == "" || txtTargetPrice.Text != txtInitialTargetPrice.Value)
            {
               bCalculateTargetPrice = false; // Calculate the discount instead
            }   
         }
 
         if (bCalculateTargetPrice)
         {
            // Calculate Target price
            decimal nPercentDiscount = Convert.ToDecimal(txtPercentageDiscount.Text);
            decimal nTargetPrice = (1 - (nPercentDiscount / 100)) * nPrice;
            
            txtTargetPrice.Text = nTargetPrice.ToString("0.00");
         }   
         else
         {
            // Calculate discount
            decimal nTargetPrice = 0;
            
            if (txtTargetPrice.Text != "")
            {
               nTargetPrice = Convert.ToDecimal(txtTargetPrice.Text);
            }

            decimal nPercentDiscount = (1 - (nTargetPrice / nPrice)) * 100;
            txtPercentageDiscount.Text = nPercentDiscount.ToString("0.000");
            
            // Refresh target price
            nPercentDiscount = Convert.ToDecimal(txtPercentageDiscount.Text);  // adjust discount precision
            nTargetPrice = (1 - (nPercentDiscount / 100)) * nPrice;
            txtTargetPrice.Text = nTargetPrice.ToString("0.00");
         }   
      }
  
      private void btnUpdateValues_Click(object sender, System.EventArgs e)
      {
         RefreshView();
      }

      private void RedirectToQuote()
      {
         m_strCloseUrl = "CustomizeQuote.aspx?id={" + guidQuoteId.ToString() + "}&oType=1084&security=852407&tabSet=ConfiguratorArea&CategoryId=" + strRootCategoryId;
         Response.Redirect(m_strCloseUrl);
      }

      private void lnkSave_Click(object sender, System.EventArgs e)
      {
         RefreshView();

         // Gather discount targets
         decimal nInitialPrice = Convert.ToDecimal(lblQuoteTotalValue.Text);
         decimal nTargetPrice = Convert.ToDecimal(txtTargetPrice.Text);
         decimal nPercentageDiscount = Convert.ToDecimal(txtPercentageDiscount.Text);
         decimal nTotalDiscount = nInitialPrice - nTargetPrice;
         
         // Remove any existings discounts
         RemoveDiscounts();

         // Apply discounts to the labor items
         decimal nLaborDiscount = DiscountLaborItems(nPercentageDiscount);

         // Revise percentage to exclude labor items and non-discountable items
         decimal nRegularItemTotal = CalcRegularItemPrice();

         if (nRegularItemTotal > 0)
         {
            decimal nRevisedDiscount = nTotalDiscount - nLaborDiscount;
            decimal nRevisedPercentDiscount = (1 - ((nRegularItemTotal - nRevisedDiscount) / nRegularItemTotal)) * 100;
            nRevisedPercentDiscount = Math.Round(nRevisedPercentDiscount, 3);

            DiscountRegularItems(nRevisedPercentDiscount);
         }

         // Save and return to quote
         SaveQuote();   
         RedirectToQuote();
      }

      private void lnkCancel_Click(object sender, System.EventArgs e)
      {
         RedirectToQuote();
      }

      private void RemoveDiscounts()
      {
         foreach (QuoteDetail objItem in objQuote.LineItems)
         {
            objItem.ApplyPercentageMultiplier(1);
         }
      }     

      // Returns total dollars saved
      private decimal DiscountLaborItems(decimal nPercentageDiscount)
      {
         decimal nLaborDiscount = 0;

         if (nPercentageDiscount > 20)
         {
            nPercentageDiscount = 20; // 20% is the maximum amount for labor items
         }

         foreach (QuoteDetail objItem in objQuote.LineItems)
         {
            if (objItem.ProductTypeCode == 3 && objItem.AllowDiscounting)
            {
               AdjustDiscount(objItem, 1 - (nPercentageDiscount / 100));
               nLaborDiscount += objItem.ManualDiscountAmount;
            }
         }

         return nLaborDiscount;
      }

      private decimal CalcRegularItemPrice()
      {
         decimal nRegularItemTotal = 0;

         foreach (QuoteDetail objItem in objQuote.LineItems)
         {
            if (objItem.ProductTypeCode != 3 && objItem.AllowDiscounting)
            {
               nRegularItemTotal += (objItem.PricePerUnit * objItem.Quantity);
            }
         }

         return nRegularItemTotal;
      }

      private void DiscountRegularItems(decimal nPercentageDiscount)
      {
         foreach (QuoteDetail objItem in objQuote.LineItems)
         {
            if (objItem.ProductTypeCode != 3 && objItem.AllowDiscounting)
            {
                AdjustDiscount(objItem, 1 - (nPercentageDiscount / 100));   
            }
         }
      }  
 
      public void AdjustDiscount(QuoteDetail objItem, decimal nDiscountPercent)
      {
         objItem.ManualDiscountAmount = 0;
         decimal nStartingPrice = objItem.PricePerUnit * objItem.Quantity;   
         decimal nTargetPrice = nStartingPrice * nDiscountPercent;

         objItem.ManualDiscountAmount = nStartingPrice - nTargetPrice;
      }

      private void SaveQuote()
      {
         foreach (QuoteDetail objItem in objQuote.LineItems)
         {
            eng.UpdateQuoteDetail(objItem);
         }
      }   

   
   
   } // end class
}
